/**
 * Copyright 2018 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.codec;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.jianggujin.codec.util.JCodecException;
import com.jianggujin.codec.util.JCodecUtils;

/**
 * 消息认证码（Message Authentication Code，MAC）算法
 * 
 * @author jianggujin
 *
 */
public class JMac {

   /**
    * Mac算法
    * 
    * @author jianggujin
    *
    */
   public static enum JMacAlgorithm {

      HmacMD5, HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA384, HmacSHA512;
      public String getName() {
         return this.name();
      }
   }

   /**
    * 初始化密钥
    * 
    * @param algorithm
    * @return
    */
   public static SecretKey initKey(JMacAlgorithm algorithm) {
      return initKey(algorithm.getName());
   }

   /**
    * 初始化密钥
    * 
    * @param algorithm
    * @return
    */
   public static SecretKey initKey(String algorithm) {
      return JCodecUtils.initKey(algorithm);
   }

   /**
    * 初始化密钥
    * 
    * @param algorithm
    * @return
    */
   public static byte[] initEncodedKey(JMacAlgorithm algorithm) {
      return initEncodedKey(algorithm.getName());
   }

   /**
    * 初始化密钥
    * 
    * @param algorithm
    * @return
    */
   public static byte[] initEncodedKey(String algorithm) {
      return initKey(algorithm).getEncoded();
   }

   /**
    * 加密
    * 
    * @param data
    * @param key
    * @param algorithm
    * @return
    */
   public static byte[] encrypt(byte[] data, byte[] key, JMacAlgorithm algorithm) {
      return encrypt(data, key, algorithm.getName());
   }

   /**
    * 加密
    * 
    * @param data
    * @param key
    * @param algorithm
    * @return
    */
   public static byte[] encrypt(byte[] data, byte[] key, String algorithm) {
      return getMac(key, algorithm).doFinal(data);
   }

   /**
    * 加密
    * 
    * @param data
    * @param secretKey
    * @return
    */
   public static byte[] encrypt(byte[] data, SecretKey secretKey) {
      return getMac(secretKey).doFinal(data);
   }

   public static Mac getMac(byte[] key, JMacAlgorithm algorithm) {
      return getMac(key, algorithm.getName());
   }

   public static Mac getMac(byte[] key, String algorithm) {
      SecretKey secretKey = new SecretKeySpec(key, algorithm);
      return getMac(secretKey);
   }

   public static Mac getMac(SecretKey secretKey) {
      try {
         Mac mac = Mac.getInstance(secretKey.getAlgorithm());
         mac.init(secretKey);
         return mac;
      } catch (Exception e) {
         throw new JCodecException(e);
      }
   }

}
